package main

import (
	"bytes"
	"gitee.com/huanminabc/go-utils/file"
	"github.com/tdewolff/minify"
	"github.com/tdewolff/minify/html"
	"github.com/tdewolff/minify/js"
	"log"
	"os"
	"os/exec"
	"strings"
)

// 声明后缀
var POSTFIX = map[string]string{
	".js":   "application/javascript",
	".css":  "text/css",
	".html": "text/html",
}

func NewMinify() *minify.M {
	// 创建一个新的minify实例
	m := minify.New()
	// 为JavaScript添加minify函数
	configMinify(m)
	return m
}

// 配置minify
func configMinify(m *minify.M) {
	//js
	m.AddFunc("application/javascript", js.Minify)
	//html
	m.AddFunc("text/html", html.Minify)
	//css
	m.AddFunc("text/css", html.Minify)
}

// 读取指定路径下符合条件的文件
func readFiles(path string) map[string][]string {
	//读取文件
	var files []string
	//判断文件类型然后放入到map中 key为地址切片
	fileMap := make(map[string][]string)
	file.GetFiles(path, &files)
	for _, fileName := range files {
		//取出文件的后缀
		postfix := file.GetFileSuffix(fileName)
		//判断是否存在
		if _, ok := POSTFIX[postfix]; ok {
			//存在则放入到map中
			fileMap[postfix] = append(fileMap[postfix], fileName)
		}
	}
	return fileMap
}

// 内容压缩 .js .css .html
func compressContext(m *minify.M, context string, postfix string) string {
	//压缩
	mime := POSTFIX[postfix]
	//压缩
	var output bytes.Buffer
	err := m.Minify(mime, &output, strings.NewReader(context))
	if err != nil {
		log.Fatalf("Minification failed for %s: %v", context, err)
	}
	return output.String() //返回压缩后的内容
}

// 文件压缩
func compressFile(m *minify.M, files map[string][]string) {
	//遍历map
	for k, v := range files {
		for _, filePath := range v {
			//压缩
			mime := POSTFIX[k]
			//读取文件
			input, err := os.ReadFile(filePath)
			if err != nil {
				log.Fatalf("Failed to read file %s: %v", filePath, err)
			}
			//压缩
			var output bytes.Buffer
			err = m.Minify(mime, &output, bytes.NewReader(input))
			if err != nil {
				log.Fatalf("Minification failed for %s: %v", filePath, err)
			}
			// 将压缩后的内容写回文件
			err = os.WriteFile(filePath, output.Bytes(), 0644)
			if err != nil {
				log.Fatalf("Failed to write file %s: %v", filePath, err)
			}
		}
	}
}

// js混淆
// 需要先安装node然后npm install uglify-js -g  记得配置node的环境变量和全局安装目录的环境变量
// uglifyjs  inputFile.js  -o  outputFile.js  -c  -m
// -c和-m选项分别用于启用代码压缩和混淆
func confuseJs(jsFiles []string) {
	//遍历文件
	for _, file := range jsFiles {
		//执行命令
		cmd := exec.Command("uglifyjs", file, "-o", file, "-c", "-m")
		err := cmd.Run()
		if err != nil {
			log.Fatalf("Failed to confuse file %s: %v", file, err)
		}
	}

}

// js 混淆,把内容输入到缓存文件中,然后执行命令,最后读取文件内容,然后删除文件,返回内容
func confuseJsContent(content string) string {
	temp, err := os.CreateTemp("", "goConfuseJsContentTemp.js")
	if err != nil {
		log.Fatalf("Failed to create temp file: %v", err)
	}
	//写入内容
	_, err = temp.WriteString(content)
	if err != nil {
		log.Fatalf("Failed to write temp file: %v", err)
	}
	//执行命令
	cmd := exec.Command("uglifyjs", temp.Name(), "-o", temp.Name(), "-c", "-m")
	err = cmd.Run()
	if err != nil {
		log.Fatalf("Failed to confuse content: %v", err)
	}
	//读取内容
	output, err := os.ReadFile(temp.Name())
	if err != nil {
		log.Fatalf("Failed to read temp file: %v", err)
	}
	//删除文件
	err = os.Remove(temp.Name())
	if err != nil {
		log.Fatalf("Failed to remove temp file: %v", err)
	}
	return string(output)
}
